﻿using Microsoft.Xna.Framework;
namespace Projectiles
{
    public class Projectile
    {
        public  Vector3 position, previousPosition; // rocket position
        private Vector3 speed;                      // relative change in X,Y,Z
        public  Matrix  directionMatrix;            // direction transformations
        public  bool    active;                     // visibility
        private float   boundary;                   // edge of world on X and Z
        private float   seconds;                    // seconds since launch

        private Vector3 startPosition;              // launch position

        public Projectile(float border)
        {
            boundary = border;
            active = false;
        }

        public void Launch(Vector3 look, Vector3 start)
        {
            position = startPosition = start;   // start at camera
            speed    = Vector3.Normalize(look); // unitize direction
            active   = true;                    // make visible
            seconds  = 0.0f;                    // used with gravity only
        }

        private void SetDirectionMatrix()
        {
            Vector3 Look  = position - previousPosition;
            Look.Normalize();

            Vector3 Up    = new Vector3(0.0f, 1.0f, 0.0f); // fake Up to get
            Vector3 Right = Vector3.Cross(Up, Look);
            Right.Normalize();

            Up = Vector3.Cross(Look, Right);               // calculate Up with
            Up.Normalize();                                // correct vectors
            
            Matrix matrix  = new Matrix();                 // compute direction matrix
            matrix.Right   = Right;
            matrix.Up      = Up;
            matrix.Forward = Look;
            matrix.M44     = 1.0f;                         // W is set to 1 to enable transforms
            directionMatrix = matrix;
        }

        public void UpdateProjectile(GameTime gameTime)
        {
            previousPosition = position;    // archive last position
            position        += speed        // update current position
                            * (float)gameTime.ElapsedGameTime.Milliseconds/90.0f;
            SetDirectionMatrix();

            // deactivate if outer border exceeded on X or Z
            if (position.Z > 2.0f * boundary || position.X > 2.0f * boundary ||
                position.Z < -2.0f * boundary || position.X < -2.0f * boundary)
                    active = false;
        }
    }
}